using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using Npgsql;

namespace AuthService.Infrastructure.HealthChecks;

/// <summary>
/// 数据库健康检查
/// 检查PostgreSQL数据库连接状态
/// </summary>
public class DatabaseHealthCheck : IHealthCheck
{
    private readonly string _connectionString;
    private readonly ILogger<DatabaseHealthCheck> _logger;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="configuration">配置</param>
    /// <param name="logger">日志记录器</param>
    public DatabaseHealthCheck(IConfiguration configuration, ILogger<DatabaseHealthCheck> logger)
    {
        _connectionString = configuration.GetConnectionString("DefaultConnection")
            ?? throw new ArgumentException("数据库连接字符串未配置");
        _logger = logger;
    }

    /// <summary>
    /// 执行健康检查
    /// </summary>
    /// <param name="context">健康检查上下文</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>健康检查结果</returns>
    public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        try
        {
            using var connection = new NpgsqlConnection(_connectionString);
            await connection.OpenAsync(cancellationToken);

            // 执行简单查询测试连接
            using var command = new NpgsqlCommand("SELECT 1", connection);
            var result = await command.ExecuteScalarAsync(cancellationToken);

            if (result != null && result.Equals(1))
            {
                _logger.LogDebug("数据库健康检查通过");
                return HealthCheckResult.Healthy("数据库连接正常");
            }
            else
            {
                _logger.LogWarning("数据库健康检查失败：查询结果异常");
                return HealthCheckResult.Unhealthy("数据库查询结果异常");
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "数据库健康检查异常");
            return HealthCheckResult.Unhealthy($"数据库连接失败: {ex.Message}", ex);
        }
    }
}

/// <summary>
/// Consul健康检查
/// 检查Consul服务连接状态
/// </summary>
public class ConsulHealthCheck : IHealthCheck
{
    private readonly Services.IConsulServiceRegistry _consulServiceRegistry;
    private readonly ILogger<ConsulHealthCheck> _logger;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="consulServiceRegistry">Consul服务注册</param>
    /// <param name="logger">日志记录器</param>
    public ConsulHealthCheck(Services.IConsulServiceRegistry consulServiceRegistry, ILogger<ConsulHealthCheck> logger)
    {
        _consulServiceRegistry = consulServiceRegistry;
        _logger = logger;
    }

    /// <summary>
    /// 执行健康检查
    /// </summary>
    /// <param name="context">健康检查上下文</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>健康检查结果</returns>
    public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        try
        {
            // 尝试获取服务实例来测试Consul连接
            var instances = await _consulServiceRegistry.GetServiceInstancesAsync("auth-service", cancellationToken);

            _logger.LogDebug("Consul健康检查通过");
            return HealthCheckResult.Healthy($"Consul连接正常，发现 {instances.Count()} 个服务实例");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Consul健康检查异常");
            return HealthCheckResult.Unhealthy($"Consul连接失败: {ex.Message}", ex);
        }
    }
}

/// <summary>
/// 应用程序健康检查
/// 检查应用程序内部状态
/// </summary>
public class ApplicationHealthCheck : IHealthCheck
{
    private readonly ILogger<ApplicationHealthCheck> _logger;
    private readonly IServiceProvider _serviceProvider;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="serviceProvider">服务提供者</param>
    /// <param name="logger">日志记录器</param>
    public ApplicationHealthCheck(IServiceProvider serviceProvider, ILogger<ApplicationHealthCheck> logger)
    {
        _serviceProvider = serviceProvider;
        _logger = logger;
    }

    /// <summary>
    /// 执行健康检查
    /// </summary>
    /// <param name="context">健康检查上下文</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>健康检查结果</returns>
    public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        try
        {
            var data = new Dictionary<string, object>();

            // 检查内存使用情况
            var memoryUsage = GC.GetTotalMemory(false);
            data.Add("memory_usage_bytes", memoryUsage);
            data.Add("memory_usage_mb", memoryUsage / 1024 / 1024);

            // 检查GC信息
            data.Add("gc_gen0_collections", GC.CollectionCount(0));
            data.Add("gc_gen1_collections", GC.CollectionCount(1));
            data.Add("gc_gen2_collections", GC.CollectionCount(2));

            // 检查线程池信息
            ThreadPool.GetAvailableThreads(out var availableWorkerThreads, out var availableCompletionPortThreads);
            ThreadPool.GetMaxThreads(out var maxWorkerThreads, out var maxCompletionPortThreads);

            data.Add("threadpool_available_worker_threads", availableWorkerThreads);
            data.Add("threadpool_available_completion_port_threads", availableCompletionPortThreads);
            data.Add("threadpool_max_worker_threads", maxWorkerThreads);
            data.Add("threadpool_max_completion_port_threads", maxCompletionPortThreads);

            // 检查应用程序运行时间
            var startTime = Environment.TickCount64;
            data.Add("uptime_milliseconds", startTime);

            // 检查关键服务是否可用
            try
            {
                using var scope = _serviceProvider.CreateScope();
                var dynamicApiService = scope.ServiceProvider.GetService<Application.Services.IDynamicApiService>();
                if (dynamicApiService == null)
                {
                    return HealthCheckResult.Degraded("动态API服务未注册", null, data);
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "检查动态API服务时发生异常");
                return HealthCheckResult.Degraded($"动态API服务检查失败: {ex.Message}", ex, data);
            }

            _logger.LogDebug("应用程序健康检查通过");
            return HealthCheckResult.Healthy("应用程序状态正常", data);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "应用程序健康检查异常");
            return HealthCheckResult.Unhealthy($"应用程序健康检查失败: {ex.Message}", ex);
        }
    }
}

/// <summary>
/// 外部依赖健康检查
/// 检查外部服务依赖状态
/// </summary>
public class ExternalDependenciesHealthCheck : IHealthCheck
{
    private readonly IHttpClientFactory _httpClientFactory;
    private readonly IConfiguration _configuration;
    private readonly ILogger<ExternalDependenciesHealthCheck> _logger;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="httpClientFactory">HTTP客户端工厂</param>
    /// <param name="configuration">配置</param>
    /// <param name="logger">日志记录器</param>
    public ExternalDependenciesHealthCheck(
        IHttpClientFactory httpClientFactory,
        IConfiguration configuration,
        ILogger<ExternalDependenciesHealthCheck> logger)
    {
        _httpClientFactory = httpClientFactory;
        _configuration = configuration;
        _logger = logger;
    }

    /// <summary>
    /// 执行健康检查
    /// </summary>
    /// <param name="context">健康检查上下文</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>健康检查结果</returns>
    public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
    {
        var data = new Dictionary<string, object>();
        var healthyDependencies = 0;
        var totalDependencies = 0;

        try
        {
            // 检查外部API依赖
            var externalApis = _configuration.GetSection("ExternalDependencies:Apis").Get<List<ExternalApiConfig>>() ?? new List<ExternalApiConfig>();

            foreach (var api in externalApis)
            {
                totalDependencies++;
                try
                {
                    using var httpClient = _httpClientFactory.CreateClient();
                    httpClient.Timeout = TimeSpan.FromSeconds(api.TimeoutSeconds);

                    var response = await httpClient.GetAsync(api.HealthCheckUrl, cancellationToken);

                    if (response.IsSuccessStatusCode)
                    {
                        healthyDependencies++;
                        data.Add($"{api.Name}_status", "healthy");
                        data.Add($"{api.Name}_response_time", response.Headers.Date?.ToString() ?? "unknown");
                    }
                    else
                    {
                        data.Add($"{api.Name}_status", $"unhealthy_status_{response.StatusCode}");
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogWarning(ex, "外部API健康检查失败: {ApiName}", api.Name);
                    data.Add($"{api.Name}_status", $"unhealthy_exception_{ex.GetType().Name}");
                }
            }

            data.Add("healthy_dependencies", healthyDependencies);
            data.Add("total_dependencies", totalDependencies);

            if (totalDependencies == 0)
            {
                return HealthCheckResult.Healthy("无外部依赖需要检查", data);
            }

            if (healthyDependencies == totalDependencies)
            {
                return HealthCheckResult.Healthy($"所有外部依赖正常 ({healthyDependencies}/{totalDependencies})", data);
            }
            else if (healthyDependencies > 0)
            {
                return HealthCheckResult.Degraded($"部分外部依赖异常 ({healthyDependencies}/{totalDependencies})", null, data);
            }
            else
            {
                return HealthCheckResult.Unhealthy($"所有外部依赖异常 ({healthyDependencies}/{totalDependencies})", null, data);
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "外部依赖健康检查异常");
            return HealthCheckResult.Unhealthy($"外部依赖健康检查失败: {ex.Message}", ex, data);
        }
    }
}

/// <summary>
/// 外部API配置
/// </summary>
public class ExternalApiConfig
{
    /// <summary>
    /// API名称
    /// </summary>
    public string Name { get; set; } = string.Empty;

    /// <summary>
    /// 健康检查URL
    /// </summary>
    public string HealthCheckUrl { get; set; } = string.Empty;

    /// <summary>
    /// 超时时间（秒）
    /// </summary>
    public int TimeoutSeconds { get; set; } = 30;
}
